import math
import random
import sys

import pygame


class Dice(pygame.sprite.Sprite):
    def __init__(self, max: int = 6, FPS=0.25):
        super().__init__()
        # 定义对象的属性
        self.FPS = FPS
        self.max = int(min(max, 6))
        # 1.all_frame为GIF动图所包含的所有帧数，这里index循环结束后为11，由于数组从0开始计算，所以为11-2=9
        self.all_frame = 4
        # 2.now_frame为当前游戏的帧，一开始设置为0
        self.now_frame = 0
        # 3.action_images为存储GIF动图的帧列表
        self.action_images: list[pygame.Surface] = []
        self.images: list[pygame.Surface] = []
        # 4.循环读取所有帧，添加到action_images[]中
        for i in range(4):
            self.action_images.append(
                pygame.image.load(f"{sys.path[0]}/img/dice_action_{i}.png")
            )
        for i in range(max + 1):
            self.images.append(pygame.image.load(f"{sys.path[0]}/img/dice_{i}.png"))
        # 5.游戏开始时设置显示第一帧图片
        self.value = 0
        self.image: pygame.Surface = self.images[0]
        self.rect = self.image.get_rect()
        self.running = False

    def start(self):
        self.running = True
        self.image = self.action_images[math.floor(self.now_frame)]

    def stop(self):
        self.running = False
        self.value = random.randint(1, self.max)
        self.image = self.images[self.value]

    def reset(self):
        self.running = False
        self.value = 0
        self.image = self.images[self.value]

    def update(self):
        if self.running:
            # 画面每次刷新更新gif的一下一帧
            self.now_frame = self.now_frame + self.FPS
            if self.now_frame >= self.all_frame:
                # 当播放到gif最后一帧时，重置为gif第一帧
                self.now_frame = 0
            # 设置pygame当前显示的gif帧
            # 使用math.floor向下取整达到降帧的效果
            self.image = self.action_images[math.floor(self.now_frame)]


class DiceGroup(pygame.sprite.Sprite):
    def __init__(self, number, max=6, bgColor=(255, 255, 255), FPS=0.25):
        super().__init__()
        self.running = False
        self.bgColor = bgColor
        self.dices: list[Dice] = []
        for i in range(number):
            self.dices.append(Dice(max, FPS))
        rect = self.dices[0].rect
        self.surface = pygame.Surface((rect.width * number, rect.height))
        self.rect = self.surface.get_rect()
        for i in range(number):
            dice = self.dices[i]
            dice.rect = (
                rect.left + rect.width * i,
                rect.top,
                rect.width,
                rect.height,
            )

    def update(self):
        self.surface.fill(self.bgColor)
        for dice in self.dices:
            dice.update()
            self.surface.blit(dice.image, dice.rect)

    def start(self):
        self.running = True
        for dice in self.dices:
            dice.start()

    def stop(self):
        self.running = False
        for dice in self.dices:
            dice.stop()

    def reset(self):
        self.running = False
        for dice in self.dices:
            dice.reset()

    # 获得当前有效的骰子值
    def get_values(self):
        values = []
        for dice in self.dices:
            value = dice.value
            if value > 0:
                values.append(value)
        return values

    # 根据点数匹配重置一个骰子
    def reset_one_of_value(self, value):
        for dice in self.dices:
            if value == dice.value:
                dice.reset()
                return True
        return False


def main():
    # 初始化pygame库
    pygame.init()
    # 标题
    pygame.display.set_caption("Dice 测试")

    # 创建游戏窗口
    screen = pygame.display.set_mode((800, 600))
    # screen.fill((204, 204, 204))

    dice = DiceGroup(6)
    dice.rect.center = screen.get_rect().center
    # 控制游戏执行的速度
    clock = pygame.time.Clock()

    # 游戏主循环
    running = True
    while running:
        clock.tick(60)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_r:
                    dice.reset()
            elif event.type == pygame.MOUSEBUTTONUP:
                if dice.running:
                    dice.stop()
                else:
                    dice.start()
        # screen.fill((204, 204, 204))
        dice.update()
        screen.blit(dice.surface, dice.rect)
        pygame.display.update()


if __name__ == "__main__":
    main()
